#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <ctype.h>
#include <sys/errno.h>
#include <sys/stat.h> /* Function to take information from a file */
#include <math.h>
#include <syslog.h>
#include <netdb.h>
#include <fcntl.h>
#include "../Headers/comm_fifo.h"
#include "../Headers/shared.h"

#define MAX_LENGHT 20
#define MAX_MSG_SIZE 235

struct fifoCDT{
	int rfd;
	int wfd;
};

fifoADT 
open_conn_fifo (hostFIFO * phost)
{
	fifoADT fifo;
	int aux_fd;
	char mypid[PID_LEN] = {0};
	char r_fifo[PID_LEN + 5] = {0};
	char w_fifo[PID_LEN + 5] = {0};
	char * aux_w, * aux_r;
	
	if ((fifo = malloc (sizeof (struct fifoCDT))) == NULL)
		return NULL;
	
	/* Primero me conecto a una FIFO conocida por todos
	 * para pedir una conexion */
	if ((aux_fd = open (phost->fifo_name, O_WRONLY)) == -1){
		free (fifo);
		return NULL;
	}
	
	/* Le envio al server mi pid para que cree una FIFO con su nombre */
	sprintf (mypid, "%d", getpid());
	write (aux_fd, mypid, strlen (mypid));
	close (aux_fd);
	/* Le doy tiempo al server para que cree el FIFO */
	sleep (2);
	
	/* Me conecto a los fifo r'pid', w'pid' */
	aux_w = w_fifo;
	aux_r = r_fifo;
	strcpy (aux_r, "/tmp/R");
	strcpy (aux_w, "/tmp/W");
	aux_r += strlen ("/tmp/R");
	aux_w += strlen ("/tmp/W");
	strcpy (aux_r, mypid);
	strcpy (aux_w, mypid);
	
	/* Los abro invertidos */
	if ((fifo->rfd = open (w_fifo, O_RDONLY | O_NONBLOCK)) == -1){
		free (fifo);
		return NULL;
	}
	if ((fifo->wfd = open (r_fifo, O_WRONLY | O_NONBLOCK)) == -1){
		close (fifo->rfd);
		free (fifo);
		return NULL;
	}
	
	return fifo;
}
int 
send_data_fifo (fifoADT conn, char * s_msg, int size)
{
	int n_size;
	
	if (size < 0 || conn == NULL || s_msg == NULL)
		return -1;
	
	n_size = write(conn->wfd, s_msg, size);
	if (n_size < 0)
		return -2;
	return 1;
}

int 
rcv_data_fifo (fifoADT conn, char * r_msg)
{
	int nread;
	int total = 0;
	
	if ( conn == NULL)
		return -1;
	
	/* Mientras haya algo para leer, leo */
	while ( (nread = read(conn->rfd, r_msg, MAX_MSG_SIZE)) > 0)
		total += nread;
	
	return 1;
}

int
getWFd_fifo (fifoADT conn)
{
	if (conn == NULL)
		return -1;
	return conn->wfd;
}

int 
getRFd_fifo (fifoADT conn)
{
	if (conn == NULL)
		return -1;
	return conn->rfd;
}

int
close_conn_fifo (fifoADT conn)
{
	if (conn == NULL)
		return -1;
	
	close (conn->rfd);
	close (conn->wfd);
	free (conn);
	return 1;
}
